/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Derived Key Set Class
 *      Represents and manages a symmetric encryption key and IV pair derived
 * from an original key and IV value.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Text;

namespace Adaptive.Foundation.Security
{
    /// <summary>
    /// Represents and manages a symmetric encryption key and IV pair derived
    /// from an original key and IV value.
    /// </summary>
    [Serializable()]
    public class DerivedKeySet : DisposableObjectBase
    {
        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// Key value for use in a symmetric encryption/decryption algorithm.
        /// </summary>
        private byte[] _key;
        /// <summary>
        /// IV value for use in a symmetric encryption/decryption algorithm.
        /// </summary>
        private byte[] _iv;
        /// <summary>
        /// Index of the item.
        /// </summary>
        private int _index;
        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public DerivedKeySet()
            : base()
        {
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="keyValue">The value of the cryptographic key.</param>
        /// <param name="ivValue">The value of the cryptographic initialization vector.</param>
        public DerivedKeySet(byte[] keyValue, byte[] ivValue)
            : base()
        {
            _key = keyValue;
            _iv = ivValue;
        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            if ((!Disposed) && (disposing))
            {
                Clear();
            }

            _iv = null;
            _key = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets the byte array containing the cryptographic key value.
        /// </summary>
        /// <value>
        /// A byte array containing the key value used in a symmetric cryptographic algorithm.
        /// </value>
        public virtual byte[] Key
        {
            get { return _key; }
            set
            {
                _key = value;
            }
        }
        /// <summary>
        /// Gets or sets the byte array containing the cryptographic initialization vector (IV) value.
        /// </summary>
        /// <value>
        /// A byte array containing the IV value used in a symmetric cryptographic algorithm.
        /// </value>
        public virtual byte[] IV
        {
            get { return _iv; }
            set
            {
                _iv = value;
            }
        }
        /// <summary>
        /// Gets or sets an ordinal index value for the instance.
        /// </summary>
        /// <value>
        /// A sequential or other ordinal value used to identify the instance.
        /// </value>
        public virtual int Index
        {
            get { return _index; }
            set
            {
                _index = value;
            }
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Clears the contents of the object instance without disposing of the instance.
        /// </summary>
        public void Clear()
        {
            if (_iv != null)
                Array.Clear(_iv, 0, _iv.Length);
            if (_key != null)
                Array.Clear(_key, 0, _key.Length);
        }
        /// <summary>
        /// Translates the internal key value into a key for DES cryptographic algorithms.
        /// </summary>
        /// <param name="tripleDes">
        /// A value indicating whether to create a Triple-DES key or a regular DES key.
        /// </param>
        /// <returns>
        /// A byte array containing the key value.
        /// </returns>
        public byte[] ToDesKey(bool tripleDes)
        {
            /* --------------------
             * AES  Key Length = 32
             * TDES Key Length = 24
             *  DES Key Length = 8
             * ---------------- */
            byte[] returnValue = null;

            if (_iv != null)
            {
                if ((tripleDes) && (_iv.Length >= 24))
                {
                    returnValue = new byte[24];
                    Array.Copy(_key, 0, returnValue, 0, 24);
                }
                else if ((!tripleDes) && (_iv.Length >= 8))
                {
                    returnValue = new byte[8];
                    Array.Copy(_key, 0, returnValue, 0, 8);
                }
            }
            return returnValue;
        }
        /// <summary>
        /// Translates the internal key value into an initialization vector (IV) for DES cryptographic algorithms.
        /// </summary>
        /// <returns>
        /// A byte array containing the IV value.
        /// </returns>
        public byte[] ToDesIV()
        {
            /* --------------------
             * AES  IV Length = 16
             * TDES IV Length = 8
             *  DES IV Length = 8
             * ---------------- */
            byte[] returnValue = null;

            if ((_iv != null) && (_iv.Length >= 8))
            {
                returnValue = new byte[8];
                Array.Copy(_iv, 0, returnValue, 0, 8);
            }

            return returnValue;
        }
        /// <summary>
        /// Returns a string representation of the current object instance.
        /// </summary>
        /// <returns>
        /// A string containing the hexadecimal representation of the key and/or iv if the 
        /// values are present.
        /// </returns>
        public override string ToString()
        {
            StringBuilder builder = null;

            builder = new StringBuilder();
            if (_key != null)
                builder.Append(Conversion.ToHexadecimal(_key));
            builder.Append(".");
            if (_iv != null)
                builder.Append(Conversion.ToHexadecimal(_iv));

            return builder.ToString();
        }
        #endregion
    }
}
